﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Account;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Identity.Settings;
using Volo.Abp.Identity;
using Volo.Abp.Settings;
using WeChat.CMS.OrganizationUnits;
using Volo.Abp.Data;
using Volo.Abp.Domain.Repositories;
using System.Drawing;

namespace WeChat.CMS.Users
{
    [RemoteService(IsEnabled = false)]
    public  class UserAppService: CMSAppService, IUserAppService
    {
    
 
        protected IAccountAppService accountAppService { get; set; }
        protected IIdentityUserRepository UserRepository { get; }
        protected IOrganizationUnitRepository OrganizationUnitRepository { get; }
        protected IIdentityUserAppService identityUserAppService { get; }
        protected IdentityUserManager UserManager { get; }
        protected IdentityUserStore _store { get; set; }
        public UserAppService(IIdentityUserRepository userRepository, IOrganizationUnitRepository organizationUnitRepository, IIdentityUserAppService IdentityUserAppService, IdentityUserManager userManager, IAccountAppService _accountAppService,  IdentityUserStore store)
        {
            UserRepository = userRepository;
            OrganizationUnitRepository = organizationUnitRepository;
            identityUserAppService = IdentityUserAppService;
            UserManager = userManager;
            accountAppService = _accountAppService;
            _store = store;
        }


        /// <summary>
        /// 创建带组织的用户
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public virtual async Task<IdentityUserDto> CreateAsync(IdentityUserOrgCreateDto input)
        {
            var identity = await identityUserAppService.CreateAsync(
                ObjectMapper.Map<IdentityUserOrgCreateDto, IdentityUserCreateDto>(input)
            );
            List<Guid> guilist = new List<Guid>();
            var orglist = await OrganizationUnitRepository.GetListAsync();
            if (input.OrgIds != null)
            {
                foreach (var item in input.OrgIds)
                {
                    OrganizationUnit ou = await OrganizationUnitRepository.FindAsync(item);
                    //var list = orglist.Where(x => x.Code.StartsWith(ou.Code)).Select(x => x.Id).ToList();
                    //foreach (var tmp in list)
                    //{
                    //    if (guilist.Where(x => x == tmp).Count() == 0)
                    //    {
                    //        guilist.Add(tmp);
                    //    }
                    //}
                    if (ou != null)
                    {
                        guilist.Add(ou.Id);
                    }


                }
                await UserManager.SetOrganizationUnitsAsync(identity.Id, guilist.ToArray());
            }

            return identity;
        }
        /// <summary>
        /// 更新带组织的用户信息
        /// </summary>
        /// <param name="id"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public virtual async Task<IdentityUserDto> UpdateAsync(Guid id, IdentityUserOrgUpdateDto input)
        {
            var update = ObjectMapper.Map<IdentityUserOrgUpdateDto, IdentityUserUpdateDto>(input);
            var result = await identityUserAppService.UpdateAsync(id, update);

            List<Guid> guilist = new List<Guid>();
            var orglist = await OrganizationUnitRepository.GetListAsync();
            if (input.RemoveOrgIds != null)
            {
                foreach (var item in input.RemoveOrgIds)
                {
                    OrganizationUnit ou = await OrganizationUnitRepository.FindAsync(item);
                    //var list = orglist.Where(x => x.Code.StartsWith(ou.Code)).Select(x => x.Id).ToList();
                    //foreach (var tmp in list)
                    //{
                    //    if (guilist.Where(x => x == tmp).Count() == 0)
                    //    {
                    //        guilist.Add(tmp);
                    //    }
                    //}
                    if (ou != null)
                    {
                        guilist.Add(ou.Id);
                    }

                }
                // await UserManager.SetOrganizationUnitsAsync(identity.Id, guilist.ToArray());
            }
            foreach (var item in guilist)
            {
                if (input.OrgIds.Where(x => x == item).Count() != 0)
                {
                    input.OrgIds.Remove(item);
                }
            }
            List<Guid> guilistinput = new List<Guid>();
            var orglistres = await OrganizationUnitRepository.GetListAsync();
            if (input.OrgIds != null)
            {
                foreach (var item in input.OrgIds)
                {
                    OrganizationUnit ou = await OrganizationUnitRepository.FindAsync(item);
                    //var list = orglistres.Where(x => x.Code.StartsWith(ou.Code)).Select(x => x.Id).ToList();
                    //foreach (var tmp in list)
                    //{
                    //    if (guilistinput.Where(x => x == tmp).Count() == 0)
                    //    {
                    //        guilistinput.Add(tmp);
                    //    }
                    //}
                    if (ou != null)
                    {
                        guilistinput.Add(ou.Id);
                    }

                }
            }

            await UserManager.SetOrganizationUnitsAsync(result.Id, guilistinput.ToArray());

            return result;
        }

        /// <summary>
        /// 添加啊用户到组织
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="ouId"></param>
        /// <returns></returns>
        public virtual async Task<bool> AddToOrganizationUnitAsync(UseToOrganizationUnitCreationDto input)
        {
            foreach (var item in input.UserId)
            {
                IdentityUser user = await UserRepository.FindAsync(item);

                //根据这个组织获取这个组织下的所有组织
                OrganizationUnit ou = await OrganizationUnitRepository.FindAsync(input.OrgId);

                var orglist = await OrganizationUnitRepository.GetListAsync();
                List<Guid> guilist = orglist.Where(x => x.Code.StartsWith(ou.Code)).Select(x => x.Id).ToList();

                //判断组织有没有
                await UserRepository.EnsureCollectionLoadedAsync(user, u => u.OrganizationUnits);


                if (user.OrganizationUnits.Any(cou => cou.OrganizationUnitId == ou.Id))
                {
                    return false;
                }

                await CheckMaxUserOrganizationUnitMembershipCountAsync(user.OrganizationUnits.Count + 1);

                foreach (var orgguid in guilist)
                {
                    user.AddOrganizationUnit(orgguid);
                    await UserRepository.UpdateAsync(user);
                }
            }
            return true;
        }
        /// <summary>
        /// 根据用户id获取该用户下所有的组织带分页的
        /// </summary>
        /// <param name="user"></param>
        /// <param name="includeDetails"></param>
        /// <returns></returns>
        public virtual async Task<PagedResultDto<OrganizationUnitEto>> GetOrganizationUnitsAsync(OrganizationUnitPagedListDto input)
        {
            IdentityUser user = await UserRepository.FindAsync(input.id);
            await UserRepository.EnsureCollectionLoadedAsync(user, u => u.OrganizationUnits);

            var list = await OrganizationUnitRepository.GetListAsync(
                user.OrganizationUnits.Select(t => t.OrganizationUnitId),
                input.includeDetails
            );

            return new PagedResultDto<OrganizationUnitEto>(
               list.Count,
               ObjectMapper.Map<List<OrganizationUnit>, List<OrganizationUnitEto>>(list)
           );
        }
        /// <summary>
        /// 根据用户id获取该用户下所有的组织不带分页
        /// </summary>
        /// <param name="id"></param>
        /// <param name="includeDetails"></param>
        /// <returns></returns>
        public virtual async Task<ListResultDto<OrganizationUnitEto>> GetListOrganizationUnitsAsync(Guid id, bool includeDetails = false)
        {
            var list = await UserRepository.GetOrganizationUnitsAsync(id, includeDetails);
            return new ListResultDto<OrganizationUnitEto>(
                ObjectMapper.Map<List<OrganizationUnit>, List<OrganizationUnitEto>>(list)
            );
        }
        /// <summary>
        /// 获取该组织下所有用户
        /// </summary>
        /// <param name="organizationUnit"></param>
        /// <param name="includeChildren"></param>
        /// <returns></returns>
        public virtual async Task<PagedResultDto<IdentityUserDto>> GetUsersInOrganizationUnitAsync(
           OrganizationUnitUsersPagedListDto input)

        {
            List<IdentityUser> list = new List<IdentityUser>();
            OrganizationUnit organizationUnit = await OrganizationUnitRepository.FindAsync(input.orgId);
            if (input.includeChildren)
            {
                list = await UserRepository
                    .GetUsersInOrganizationUnitWithChildrenAsync(organizationUnit.Code);
            }
            else
            {
                list = await UserRepository
                    .GetUsersInOrganizationUnitAsync(organizationUnit.Id);
            }
            return new PagedResultDto<IdentityUserDto>(
               list.Count,
               ObjectMapper.Map<List<IdentityUser>, List<IdentityUserDto>>(list.Skip(input.SkipCount).Take(input.MaxResultCount).ToList())
           );
        }

        /// <summary>
        /// 移除该组织下所有的用户
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="ouId"></param>
        /// <returns></returns>
        public virtual async Task<bool> RemoveFromOrganizationUnitAsync(UseToOrganizationUnitDeleteDto input)
        {
            var user = await UserRepository.GetAsync(input.UserId);
            user.RemoveOrganizationUnit(input.OrgId);
            await UserRepository.UpdateAsync(user);
            return true;
        }


        private async Task CheckMaxUserOrganizationUnitMembershipCountAsync(int requestedCount)
        {
            var maxCount =
                await SettingProvider.GetAsync<int>(IdentitySettingNames.OrganizationUnit.MaxUserMembershipCount);
            if (requestedCount > maxCount)
            {
                throw new BusinessException(IdentityErrorCodes.MaxAllowedOuMembership)
                    .WithData("MaxUserMembershipCount", maxCount);
            }
        }
        //获取所有得用户
        public async Task<List<IdentityUserDto>> GetListAllAsync()
        {
            var res = await UserRepository.GetListAsync();

            return ObjectMapper.Map<List<IdentityUser>, List<IdentityUserDto>>(res);
        }

        /// <summary>
        /// 是否激活 /不激活
        /// </summary>
        /// <returns></returns>
        public async Task<bool> UpdateUseActiveAsync(UpdateUseActiveDto input)
        {
            var res = await UserRepository.FindAsync(input.Id);
            if (res == null)
            {
                throw new UserFriendlyException($"该用户不存在，请检查");
            }
            res.SetIsActive(input.IsActive);
            await UserRepository.UpdateAsync(res);
            return true;
        }
        /// <summary>
        /// 解锁
        /// </summary>
        /// <returns></returns>
        public async Task<bool> UpdateUseLockAsync(Guid id)
        {
            var res = await UserRepository.FindAsync(id);
            if (res == null)
            {
                throw new UserFriendlyException($"该用户不存在，请检查");
            }
            if (res.LockoutEnd == null)
            {
                DateTimeOffset dateTimeOffset = new DateTimeOffset(DateTime.Now.AddHours(1));
                await _store.SetLockoutEndDateAsync(res, dateTimeOffset);
            }
            else
            {
                await _store.SetLockoutEndDateAsync(res, null);
            }
            return true;
        }

        //weixin app 修改头像
        public async Task<string> UpdateAvatorAsync(UpdateAvatorDto input)
        {
            var users = await UserRepository.GetListAsync();
            var user = users.FirstOrDefault(x => x.GetProperty<string>("WeChatOpenId") == input.OpenId.Trim());

            if (user != null)
            {
                string result = string.Empty;
                try
                {
                    //读取文件流
                    Stream stream = input.FormFile.OpenReadStream();
                    Bitmap bmp = new Bitmap(stream);
                    MemoryStream ms = new MemoryStream();
                    bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                    byte[] arr = new byte[ms.Length];
                    ms.Position = 0;
                    ms.Read(arr, 0, (int)ms.Length);
                    ms.Close();
                    result = "data:image/jpeg;base64," + Convert.ToBase64String(arr);

                    user.SetProperty("Avatar", result);
                    await UserRepository.UpdateAsync(user);
                }
                catch (Exception ex)
                {
                    result = string.Empty;
                }
                return result;
            }
            else
            {
                throw new UserFriendlyException($"用户不存在不存在，请检查");
            }
        }

        public async Task<bool> DeleteUseInfo(Guid userid)
        {
            var res = await UserRepository.FindAsync(userid);
            await UserRepository.DeleteAsync(userid);
            return true;
        }


    }
}
